package cn.remex.wechat.config;

import cn.remex.RemexConstants;
import cn.remex.core.exception.ServiceCode;
import cn.remex.core.util.*;
import cn.remex.db.Database;
import cn.remex.web.service.BsException;
import cn.remex.wechat.WeChat;
import cn.remex.wechat.beans.WeChatUserOpenIdList;
import cn.remex.wechat.beans.messages.*;
import cn.remex.wechat.beans.paymch.WeChatPayResult;
import cn.remex.wechat.beans.paymch.WeChatUnifiedorder;
import cn.remex.wechat.beans.paymch.WeChatUnifiedorderResult;
import cn.remex.wechat.models.WeChatMsg;

import java.io.File;
import java.util.UUID;
import java.util.function.Consumer;

/**
 * 名称：
 * 缩写：
 * 用途：
 * Created by yangy on 2016/8/24 0024.
 */
public class WeChatAppExt {
	public WeChatAppExt(WeChatApp weChatApp) {
		this.weChatApp = weChatApp;
	}

	private WeChatApp weChatApp;

	public WeChatApp getWeChatApp() {
		return weChatApp;
	}

	public void setWeChatApp(WeChatApp weChatApp) {
		this.weChatApp = weChatApp;
	}

	/*
	 *  微信支付
	 * @param payType  可以为空， 默认 JSAPI 支付    NATIVE： 扫码
	 */
	public WeChatPayResult pay(String desc, String orderId, String money, String openId, String payType){
		Assert.notNullAndEmpty(weChatApp.getConfig().getMchid(),ServiceCode.FAIL,"没有配置微信支付商户账户信息");
		payType = Judgment.nullOrBlank(payType)?"JSAPI":payType;
		Assert.isTrue("JSAPI;NATIVE;APP".contains(payType),ServiceCode.FAIL,"支付类型只能为JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付");
		RemexConstants.logger.info("微信付款："+desc+"金额："+money);
		WeChatUnifiedorder weChatUnifiedorder = new WeChatUnifiedorder();
		weChatUnifiedorder.setAppid(weChatApp.getConfig().getAppid());
		weChatUnifiedorder.setMch_id(weChatApp.getConfig().getMchid());
		weChatUnifiedorder.setNonce_str(UUID.randomUUID().toString().replace("-", ""));
		weChatUnifiedorder.setBody(desc);
		weChatUnifiedorder.setOut_trade_no(orderId);
		weChatUnifiedorder.setTotal_fee(money);
		weChatUnifiedorder.setSpbill_create_ip("192.168.1.1");
		weChatUnifiedorder.setNotify_url(weChatApp.getConfig().getPayBackUrl());
		weChatUnifiedorder.setTrade_type(payType);
		//谁删的 !! 我保证不打死他!
		// payType  二维码扫码不能传入openid, 否则会出现 下单账号和支付账号不一致!
		// 再删就打死你!
		if("JSAPI".equals(payType)){
			weChatUnifiedorder.setOpenid(openId);
		}
		WeChatUnifiedorderResult weChatUnifiedorderResult = weChatApp.payUnifiedorder(weChatUnifiedorder);
		if("SUCCESS".equals(weChatUnifiedorderResult.getReturn_code())){
			WeChatPayResult weChatPay = new WeChatPayResult();
			if("SUCCESS".equals(weChatUnifiedorderResult.getResult_code())){
				RemexConstants.logger.info("微信付款预下单成功！");
				weChatPay.setCode(weChatUnifiedorderResult.getResult_code());
				weChatPay.setPrepay_id(weChatUnifiedorderResult.getPrepay_id());
				weChatPay.setUrl(weChatUnifiedorderResult.getCode_url());
				return weChatPay;
			}else{
				RemexConstants.logger.info("微信付款发生错误！"+"错误代码："+weChatUnifiedorderResult.getErr_code()+"错误原因："+weChatUnifiedorderResult.getErr_code_des());
				weChatPay.setCode(weChatUnifiedorderResult.getErr_code());
				weChatPay.setMsg(weChatUnifiedorderResult.getErr_code_des());
				return weChatPay;
			}
		}
		RemexConstants.logger.info("微信付款预网络错误！");
		return null;
	}


	/*
	 * 微信模板消息接口
	 */
	public boolean messageTemplateSend(TemplateMessage templateMessage){
		String access_token = weChatApp.getAccess_token();
		Assert.notNull(access_token,  ServiceCode.ERROR,"null access_token");
		Assert.notNull(templateMessage,  ServiceCode.ERROR,"empty templateMessage");
		String data = JsonHelper.toJsonString(templateMessage);

		WeChatMsg weChatMsg = new WeChatMsg();
		weChatMsg.setFromUserName(weChatApp.getConfig().getAppid());
		weChatMsg.setToUserName(templateMessage.getTouser());
		weChatMsg.setContent(templateMessage.getData().get("first").getValue()); //first key的内容是主要显示内容
		weChatMsg.setWxCreateTime(System.currentTimeMillis());

		try {
			WeChatMessageResult weChectMessageResult = weChatApp.templatMsgSend(templateMessage);

			weChatMsg.setErrcode(weChectMessageResult.getErrcode());
			weChatMsg.setErrmsg(weChectMessageResult.getErrmsg());
		}finally {
			Database.getSession().store(weChatMsg);
		}
		return "0".equals(weChatMsg.getErrcode());
	}


	/*
	 * 发送普通文本消息，用户发生以下事件
	 * 1、用户发送信息
	 2、点击自定义菜单（仅有点击推事件、扫码推事件、扫码推事件且弹出“消息接收中”提示框这3种菜单类型是会触发客服接口的）
	 3、关注公众号
	 4、扫描二维码
	 5、支付成功
	 6、用户维权

	 则48h以内可以发送消息给用户
	 */
	public boolean sendCustomWeChatMsg(String openId, String msgContent) {
		String access_token = weChatApp.getAccess_token();
		Assert.notNull(access_token, ServiceCode.ERROR, "invalid access_token");
		Assert.notNull(msgContent, ServiceCode.ERROR, "invalid msgContent");
		CustomMsg customMsg = new CustomMsg();
		customMsg.setTouser(openId);
		customMsg.setMsgtype("text");
		customMsg.setText(new CustomMsgData(msgContent));

		WeChatMsg weChatMsg = new WeChatMsg();
		weChatMsg.setFromUserName(weChatApp.getConfig().getAppid());
		weChatMsg.setToUserName(openId);
		weChatMsg.setContent(msgContent);
		weChatMsg.setWxCreateTime(System.currentTimeMillis());
		try {
			WeChatMessageResult weChectMessageResult = weChatApp.customMsgSend(customMsg);

			weChatMsg.setErrcode(weChectMessageResult.getErrcode());
			weChatMsg.setErrmsg(weChectMessageResult.getErrmsg());
		}finally {
			Database.getSession().store(weChatMsg);
		}
		return "0".equals(weChatMsg.getErrcode());
	}

	public boolean sendnewCustomWeChatMsg(String openId, String mpnewsId) {
		String access_token = weChatApp.getAccess_token();
		Assert.notNull(access_token, ServiceCode.ERROR, "invalid access_token");
		Assert.notNull(mpnewsId, ServiceCode.ERROR, "invalid msgContent");
		CustomMsg customMsg = new CustomMsg();
		customMsg.setTouser(openId);
		customMsg.setMsgtype("mpnews");
		CustomMsgData customMsgData =  new CustomMsgData(null);
		customMsgData.setMedia_id(mpnewsId);
		customMsg.setMpnews(customMsgData);
		String data = JsonHelper.toJsonString(customMsg);

		WeChatMsg weChatMsg = new WeChatMsg();
		weChatMsg.setFromUserName(weChatApp.getConfig().getAppid());
		weChatMsg.setToUserName(openId);
		weChatMsg.setContent(data);
		weChatMsg.setWxCreateTime(System.currentTimeMillis());

		try {
			WeChatMessageResult weChectMessageResult = weChatApp.customMsgSend(customMsg);

			weChatMsg.setErrcode(weChectMessageResult.getErrcode());
			weChatMsg.setErrmsg(weChectMessageResult.getErrmsg());
		}finally {
			Database.getSession().store(weChatMsg);
			return "0".equals(weChatMsg.getErrcode());
		}
	}

	public void everyWeChatUserOpenId(Consumer<String> openIdConsumer) {
		WeChatUserOpenIdList weChatUserOpenIdList = weChatApp.obtainOpenIdList("");
		do{
			if (Judgment.nullOrBlank(weChatUserOpenIdList.getErrcode()) && weChatUserOpenIdList.getData() != null && weChatUserOpenIdList.getData().getOpenid() != null) {
				weChatUserOpenIdList.getData().getOpenid().forEach(openIdConsumer);
			} else {
				throw new BsException("微信--获取用户信息失败！");
			}
			weChatUserOpenIdList = weChatApp.obtainOpenIdList(weChatUserOpenIdList.getNext_openid());
		}while(!Judgment.nullOrBlank(weChatUserOpenIdList.getNext_openid()));
	}
	public File getMediaAsFile(String media_id,String filePath){
		Param<File> fileParam = new Param<>();
		weChatApp.media_get(media_id,inputStream -> {
			fileParam.param = FileHelper.saveFile(filePath,inputStream);
		});
		return fileParam.param;
	}
}
